package cn.tedu.charging.device.repository.impl;

import cn.tedu.charging.common.pojo.po.ChargingGunInfoPO;
import cn.tedu.charging.common.pojo.po.ChargingStationPO;
import cn.tedu.charging.common.pojo.query.NearStationsQuery;
import cn.tedu.charging.device.mapper.GunMapper;
import cn.tedu.charging.device.mapper.StationMapper;
import cn.tedu.charging.device.repository.DeviceRepository;
import cn.tedu.charging.device.warm.StationWarmUp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.GeoResult;
import org.springframework.data.redis.connection.RedisCommands;
import org.springframework.data.redis.connection.RedisGeoCommands;
import org.springframework.data.redis.core.GeoOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.concurrent.TimeUnit;

@Repository
@Slf4j
public class DeviceRepositoryImpl implements DeviceRepository {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private StationMapper stationMapper;
    @Autowired
    private GunMapper gunMapper;
    @Override
    public List<GeoResult> nearStations(NearStationsQuery query) {
        //仓储层实现 查询redis 读取geo命中数据
        //georadius charging:stations:all lng lat radius withdist withcoord
        //1.redisTemplate做geo读写 先获取客户端子对象
        GeoOperations geoOps = redisTemplate.opsForGeo();
        //2.raidus方法 key(预热类的常量) circle(point,distance) args(withdist withcoord)
        Circle circle=new Circle(query.getLongitude(),query.getLatitude(),query.getRadius());
        RedisGeoCommands.GeoRadiusCommandArgs args=RedisGeoCommands.GeoRadiusCommandArgs.newGeoRadiusArgs();
        args.includeDistance().includeCoordinates();
        return geoOps.radius(StationWarmUp.ALL_STATIONS,circle,args).getContent();
    }
    //TODO
    @Override
    public String getStationName(Integer stationId) {
        return "";
    }

    @Override
    public ChargingStationPO getStationById(Integer stationId) {
        //version1 直接调用持久层 查询id对应的场站数据
        //version2 缓存读流程
        String stationKey="charging:station:detail:"+stationId;
        ValueOperations<String,ChargingStationPO> stringOps = redisTemplate.opsForValue();
        //1.读缓存
        ChargingStationPO po = stringOps.get(stationKey);
        //判断命中
        if (po==null){
            //2.未命中 打到数据库
            log.debug("缓存未命中,stationId:{}",stationId);
            po = stationMapper.selectById(stationId);
            //3.回填缓存 如果不允许永久
            stringOps.set(stationKey,po,2, TimeUnit.DAYS);
        }
        return po;
    }

    @Override
    public List<ChargingGunInfoPO> getGunListByStationId(Integer stationId) {
        return gunMapper.selectByStationId(stationId);
    }
    //TODO
    @Override
    public Boolean updateGunStatus(Integer gunId, Integer status, List<Integer> integers) {
        return null;
    }
}
